package com.xiyou.week04.bfs;

import java.util.*;

/**
 * 329. 矩阵中的最长递增路径
 *
 * @ClassName：LongestIncreasingPath
 * @Author：西柚
 * @Date：2022/1/21 10:48 下午
 * @Versiion：1.0
 */
public class LongestIncreasingPath {

    int m, n;
    Map<Integer, List<Integer>> to = new HashMap<Integer, List<Integer>>();
    int[] deg;
    int[] dist;

    public int longestIncreasingPath(int[][] matrix) {
        m = matrix.length;
        n = matrix[0].length;
        deg = new int[m * n];
        dist = new int[m * n];
        for (int i = 0; i < m * n; i++) {
            deg[i] = 0;
            dist[i] = 0;
            to.put(i, new ArrayList<Integer>());
        }

        int[] dx = {-1, 0, 0, 1};
        int[] dy = {0, -1, 1, 0};
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < 4; k++) {
                    int ni = i + dx[k];
                    int nj = i + dy[k];
                    if (valid(ni, nj) && matrix[ni][nj] > matrix[i][j]) {
                        addEdge(num(i, j), num(ni, nj));
                    }
                }
            }
        }

        Queue<Integer> q = new LinkedList<Integer>();
        for (int i = 0; i < m * n; i++) {
            if (deg[i] == 0) {
                q.add(i);
                dist[i] = 1;
            }
        }
        while (!q.isEmpty()) {
            int x = q.poll();
            for (int y : to.get(x)) {
                deg[y]--;
                dist[y] = Math.max(dist[y], dist[x] + 1);
                if (deg[y] == 0) {
                    q.add(y);
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < m * n; i++) {
            ans = Math.max(ans, dist[i]);
        }
        return ans;
    }

    private void addEdge(int u, int v) {
        deg[v]++;
        to.get(u).add(v);
    }

    private int num(int i, int j) {
        return i * n + j;
    }

    private boolean valid(int i, int j) {
        return i >= 0 && i < m && j >= 0 && j < n;
    }

    public static void main(String[] args) {
        LongestIncreasingPath longestIncreasingPath = new LongestIncreasingPath();
        System.out.println(longestIncreasingPath.longestIncreasingPath(new int[][]{{9, 9, 4}, {6, 6, 8}, {2, 1, 1}}));
    }
}
